
#include "hmi_info.h"
#include "main.h"

pwr_monitor_sta_t	g_st_pwr_err_vin;
pwr_monitor_sta_t	g_st_pwr_err_coil;


 void hmi_get_rx_dat( uint8_t *UART1_RXBUFFER_TEMP)
{
	uint16_t	u16_crc16	= 0u;
	uint16_t	u16_crc_frame	= 0u;
	uint16_t  u16_password=0u;
	uint8_t   u8_relength=0u;
	u8_relength=UART_MAXLENGTH-DMA_GetCurrDataCounter(DMA1_Channel5);  //总-剩余单元
	if (u8_relength != 0u)
	{
	  if((UART1_RXBUFFER_TEMP[0] == DRE_SD) && (UART1_RXBUFFER_TEMP[u8_relength-1u] == DRE_ED))
		{
			  u16_crc16 = CodeCRCCal((uint8_t*)UART1_RXBUFFER_TEMP, u8_relength-3u);
			  u16_crc_frame = UART1_RXBUFFER_TEMP[u8_relength-3u]+(UART1_RXBUFFER_TEMP[u8_relength-2u]*256u);
			  if (u16_crc16==u16_crc_frame)	//帧通讯正确
				{
					    u16_password=UART1_RXBUFFER_TEMP[4]+(UART1_RXBUFFER_TEMP[5]*256u);
				  		if ((u16_password==0xAAAAu)||(u16_password==0x5555u)||(u16_password==g_st_ram1.config_parameter.factory_config_pra.u16_password))
								 {
									 u8_uart_fuction =UART1_RXBUFFER_TEMP[1]; //通讯命令赋值到RAM中
									 b8_uart_reflag=BTRUE; //通讯接收到完整帧
								 }
						 else
								 {
									 ;
								 }
				}
				else
				{
					;
				}
		}
		//else if(UART1_RXBUFFER_TEMP[0]==g_st_ram1.config_parameter.factory_config_pra.u8_config_id)     //modbus调试用
		else if(UART1_RXBUFFER_TEMP[0]==g_st_ram1.config_parameter.factory_config_pra.u8_modbus_add)  //增加modbus协议解析,先判断地址
		{
			  
			  u16_crc16 = CodeCRCCal((uint8_t*)UART1_RXBUFFER_TEMP, u8_relength-2u);
			  u16_crc_frame = UART1_RXBUFFER_TEMP[u8_relength-1u]+(UART1_RXBUFFER_TEMP[u8_relength-2u]*256u); //modbus CRC和 uart的顺序有调整
			
			if (u16_crc16==u16_crc_frame)	//若符合modbus协议
				{
					     
					u8_uart_fuction = UART1_RXBUFFER_TEMP[1]+100u; //通讯命令赋值到RAM中,并且增加100,这样和Uart命令区别开来
					b8_uart_reflag=BTRUE; //通讯接收到完整帧
				}
				else
				{
					;
				}
		}
		else
		{
			;
		}
	}
	else
	{
		;
	}
}

   void hmi_handle_rx_dat( const uint8_t *UART1_RXBUFFER_TEMP,uint8_t *UART1_TXBUFFER_TEMP)
{
	uint8_t	*u8p_tmp1	= (uint8_t *)&g_st_ram1;
	uint8_t	*u8p_tmp2	= (uint8_t *)&g_st_ram2;
	uint8_t u8_mcu_addr=0u;
	uint8_t u8_uart_fc=0u;
	uint16_t u16_idx=0u;
	uint16_t u16_crc_frame=0u;
	uint16_t u16_headaddress; //定义RAM头数据地址,从0开始，代表第一个
	uint8_t  u8_length;       //定义RAM需要读写的长度，包括头
	//u8_uart_fc = UART1_RXBUFFER_TEMP[1]; //取得当前命令
	u8_uart_fc = u8_uart_fuction; //取得当前命令
	if (u8_uart_fc > 100u) //
	{
		u8_mcu_addr=0x01;     //modbus协议由单片机2进行回复
	}
	else
	{
	  u8_mcu_addr= UART1_RXBUFFER_TEMP[2]; //取得需要回复的MCU地址
	}
	
	u8p_tmp1	= (uint8_t *)&g_st_ram1;
	u8p_tmp2	= (uint8_t *)&g_st_ram2;
	if (u8_mcu_addr==g_st_ram1.run_display_data.instrument_hmi.u8_mcu_addr)
	{

		switch (u8_uart_fc)
		{
			case UART_CMD_READ:  //01读
			{
			  u16_headaddress=UART1_RXBUFFER_TEMP[6]+(UART1_RXBUFFER_TEMP[7]*256u);
				u8_length=UART1_RXBUFFER_TEMP[8];
				if((u16_headaddress+u8_length)<DRAM_MAX_SIZE)
				{
					for(u16_idx = 0u; u16_idx < 9u; u16_idx ++)
					{
						UART1_TXBUFFER_TEMP[u16_idx]=UART1_RXBUFFER_TEMP[u16_idx];
					}
					for(u16_idx = 9u; u16_idx < (10u+u8_length); u16_idx ++)
					{
					  //UART1_TXBUFFER[u16_idx] = (uint8_t*)(&g_st_ram1+u16_headaddress+u8_length);
						UART1_TXBUFFER_TEMP[u16_idx]=*(u8p_tmp1+u16_headaddress);
						u8p_tmp1++;
					}
					/* 完成读操作后，让仪表进入正常运行状态*/
					u8_uart_fuction=0u;
					u16_crc_frame=CodeCRCCal((uint8_t*)UART1_TXBUFFER_TEMP, (9u+u8_length));
					UART1_TXBUFFER_TEMP[9u+u8_length]=(uint8_t)(u16_crc_frame&0x00FFu);        //取CRC校验低位
					UART1_TXBUFFER_TEMP[10u+u8_length]=(uint8_t)((u16_crc_frame>>8)&0x00FFu);  //取CRC校验高位
					UART1_TXBUFFER_TEMP[11u+u8_length]=DRE_ED;                              //帧尾
					USART1_DMA_SEND(12u+u8_length);                                     //开始发送
				}
				else
				{
					;
				}
			}break;
			case UART_CMD_WRITE:
			{
			  u16_headaddress=UART1_RXBUFFER_TEMP[6]+(UART1_RXBUFFER_TEMP[7]*256u);
				u8_length=UART1_RXBUFFER_TEMP[8];
				if((u16_headaddress+u8_length)<CONFIG_RAM_MAX_SIZE)
				{
					for(u16_idx = 9u; u16_idx < (9u+u8_length); u16_idx ++)
					{
					  *(u8p_tmp1+u16_headaddress)=UART1_RXBUFFER_TEMP[u16_idx];//写RAM
						*(u8p_tmp2+u16_headaddress)=UART1_RXBUFFER_TEMP[u16_idx];//写RAM
						u8p_tmp1++;
						u8p_tmp2++;
					}
					/* 完成写操作后*/
					
					
					for(u16_idx = 0u; u16_idx < 9u; u16_idx ++)
					{
						UART1_TXBUFFER_TEMP[u16_idx]=UART1_RXBUFFER_TEMP[u16_idx];
					}
					u16_crc_frame=CodeCRCCal((uint8_t*)UART1_TXBUFFER, 9u);
					UART1_TXBUFFER_TEMP[9]=(uint8_t)(u16_crc_frame&0x00FFu);        //取CRC校验低位
					UART1_TXBUFFER_TEMP[10]=(uint8_t)((u16_crc_frame>>8)&0x00FFu);  //取CRC校验高位
					UART1_TXBUFFER_TEMP[11]=DRE_ED;                              //帧尾
					USART1_DMA_SEND(12u);                                     //开始发送
				}
				else
				{
					;
				}
			}break; 
		 case UART_CMD_FLASH:          //备份RAM到FLASH
		 case UART_CMD_RELAYOUTPUT:
		 case UART_CMD_ALLOUTPUT: 
		 case UART_CMD_REDLED_ON:
		 case UART_CMD_REDLED_OFF: 
			{
         for(u16_idx = 0u; u16_idx < 9u; u16_idx ++)
					{
						UART1_TXBUFFER_TEMP[u16_idx]=UART1_RXBUFFER_TEMP[u16_idx];
					}
				USART1_DMA_SEND(9u);                                     //开始发送
				soft_dly_us(10000);	                                     //延时等待
			}break;
		 case MODBUS_CMD_READ_COIL:  //modbus 读取输出
		 {
			 UART1_TXBUFFER_TEMP[0]=UART1_RXBUFFER_TEMP[0];   //modbus地址
			 UART1_TXBUFFER_TEMP[1]=UART1_RXBUFFER_TEMP[1];   //Modbus功能
		   UART1_TXBUFFER_TEMP[2]=0x02;                     //字节数
			 UART1_TXBUFFER_TEMP[3]=(uint8_t)g_st_ram1.run_display_data.instrument_hmi.u16_do; 
			 UART1_TXBUFFER_TEMP[4]=0x00;
			 u16_crc_frame=CodeCRCCal((uint8_t*)UART1_TXBUFFER, 5u);
			 UART1_TXBUFFER_TEMP[5]=(uint8_t)((u16_crc_frame>>8)&0x00FFu);   //取CRC校验高位
			 UART1_TXBUFFER_TEMP[6]=(uint8_t)(u16_crc_frame&0x00FFu);        //取CRC校验低位
			 //u8_uart_fuction=0u;                                             //读完一帧，恢复正常运行，该语句意义不大，在输出部分没有对Mobus的通讯进行处理
			 USART1_DMA_SEND(7u); 
		 }break;
		 case MODBUS_CMD_READ_IN:  //modbus 读取输入
		 {
			 UART1_TXBUFFER_TEMP[0]=UART1_RXBUFFER_TEMP[0];   //modbus地址
			 UART1_TXBUFFER_TEMP[1]=UART1_RXBUFFER_TEMP[1];   //Modbus功能
		   UART1_TXBUFFER_TEMP[2]=0x02;                     //字节数
			 UART1_TXBUFFER_TEMP[3]=(uint8_t)g_st_ram1.run_display_data.instrument_hmi.u16_di; 		 
			 UART1_TXBUFFER_TEMP[4]=(uint8_t) (g_st_ram1.run_display_data.instrument_hmi.u16_di >> 8u);  //DI高四位
			 u16_crc_frame=CodeCRCCal((uint8_t*)UART1_TXBUFFER, 5u);
			 UART1_TXBUFFER_TEMP[5]=(uint8_t)((u16_crc_frame>>8)&0x00FFu);   //取CRC校验高位
			 UART1_TXBUFFER_TEMP[6]=(uint8_t)(u16_crc_frame&0x00FFu);        //取CRC校验低位
			 //u8_uart_fuction=0u;                                             //读完一帧，恢复正常运行，该语句意义不大，在输出部分没有对Mobus的通讯进行处理
			 USART1_DMA_SEND(7u); 
		 }break;
		 case MODBUS_CMD_READ_IN_REG:  //modbus 读取输入寄存器
		 {
			  u16_headaddress=UART1_RXBUFFER_TEMP[3]*2u+(UART1_RXBUFFER_TEMP[2]*512u)+312u;    //取得Modbus输入寄存器首地址，输入寄存器首地址为g_st_ram1的210单元
			  u8_length =(uint8_t)(UART1_RXBUFFER_TEMP[5]*2+(UART1_RXBUFFER_TEMP[4]*512u));  //取得长度,且不能为0
			 if((u8_length<41u)&&(u8_length>0u))             //限制最大长度为40  这是转化为字节的长度
				{
				    UART1_TXBUFFER_TEMP[0]=UART1_RXBUFFER_TEMP[0];   //modbus从站地址
			      UART1_TXBUFFER_TEMP[1]=UART1_RXBUFFER_TEMP[1];   //Modbus功能
					  UART1_TXBUFFER_TEMP[2]=u8_length;                //字节数
					for(u16_idx = 3u; u16_idx < (3u+u8_length); u16_idx ++)
					{
					  //UART1_TXBUFFER[u16_idx] = (uint8_t*)(&g_st_ram1+u16_headaddress+u8_length);
						UART1_TXBUFFER_TEMP[u16_idx]=*(u8p_tmp1+u16_headaddress);
						u8p_tmp1++;
					}
					/* 完成读操作后，让仪表进入正常运行状态*/
					//u8_uart_fuction=0u;                                             //读完一帧，恢复正常运行，该语句意义不大，在输出部分没有对Mobus的通讯进行处理
					u16_crc_frame=CodeCRCCal((uint8_t*)UART1_TXBUFFER_TEMP, (3u+u8_length));
					UART1_TXBUFFER_TEMP[3u+u8_length]=(uint8_t)((u16_crc_frame>>8)&0x00FFu);  //取CRC校验高位
					UART1_TXBUFFER_TEMP[4u+u8_length]=(uint8_t)(u16_crc_frame&0x00FFu);        //取CRC校验低位
					USART1_DMA_SEND(5u+u8_length);                                     //开始发送
				}
				else
				{
					;
				}
		 }break;
			
		 default : break; 
		}
		
	}
	else
	{
		;
	}
}

void hmi_set_do_fault(uint8_t u8_ch, uint16_t u16_fault_code)
{
   switch(u8_ch)
		 {
		case DIAG_DO_IDX_54 :
			{
			   if(u16_fault_code!=0u)
				 {//有故障
					 g_st_ram1.run_display_data.instrument_hmi.u32_st_dev_sta |= U32_SET_BIT[22];
				 }
			   else
				 {
					 g_st_ram1.run_display_data.instrument_hmi.u32_st_dev_sta &= U32_CLR_BIT[22];
				 }
			 break;
		  }
		case DIAG_DO_IDX_34 :
			{
				if(u16_fault_code!=0u)
				 {//有故障
					 g_st_ram1.run_display_data.instrument_hmi.u32_st_dev_sta |= U32_SET_BIT[20];
				 }
			   else
				 {
					 g_st_ram1.run_display_data.instrument_hmi.u32_st_dev_sta &= U32_CLR_BIT[20];
				 }
			
			break;
		  }
		case DIAG_DO_IDX_44 :
			{  
				if(u16_fault_code!=0u)
				 {//有故障
					 g_st_ram1.run_display_data.instrument_hmi.u32_st_dev_sta |= U32_SET_BIT[21];
				 }
			   else
				 {
					 g_st_ram1.run_display_data.instrument_hmi.u32_st_dev_sta &= U32_CLR_BIT[21];
				 }
			break;
		  }
		case DIAG_DO_IDX_64 :
			{
				if(u16_fault_code!=0u)
				 {//有故障
					 g_st_ram1.run_display_data.instrument_hmi.u32_st_dev_sta |= U32_SET_BIT[23];
				 }
			   else
				 {
					 g_st_ram1.run_display_data.instrument_hmi.u32_st_dev_sta &= U32_CLR_BIT[23];
				 }	
			break;
		  }
		default : break;
	}
	g_st_ram2.run_display_data.instrument_hmi.u32_st_dev_sta = g_st_ram1.run_display_data.instrument_hmi.u32_st_dev_sta;
}

void hmi_cycle_update(const uint8_t u8lc_init_val, const uint8_t u8lc_incr_val)
{ 
	 diag_rcd_run_logic(u8lc_init_val, u8lc_incr_val);//程序序列自检
	 if(b8_uart_reflag==BTRUE) //若有通讯数据，则进行串口处理
	 {
		  //dre_protocol_poll(); //增强SPI通讯可靠性
		  hmi_handle_rx_dat( &UART1_RXBUFFER[0],&UART1_TXBUFFER[0]);
		  b8_uart_reflag=BFALSE;   //接收UART空闲状态位

	 }
	 else
	 {
		b8_uart_txflag=BFALSE;   //发送UART状态位 
	 }
	 hmi_fill_dev_diag(); 
}

void hmi_init_val(void)
{
	g_st_pwr_err_vin.u16_pram_uv	= PWR_VIN_UV;
	g_st_pwr_err_vin.u16_pram_ov	= PWR_VIN_OV;
	g_st_pwr_err_vin.b8_err			= BFALSE;
	g_st_pwr_err_vin.st_tim_fault.u16_cnt		= 0u;
	g_st_pwr_err_vin.st_tim_fault.u16_tim_old	= comm_tim_get_currt_cnt();
	g_st_pwr_err_vin.st_tim_reco.u16_cnt		= 0u;
	g_st_pwr_err_vin.st_tim_reco.u16_tim_old	= comm_tim_get_currt_cnt();
	
	g_st_pwr_err_coil.u16_pram_uv	= PWR_COIL_UV;
	g_st_pwr_err_coil.u16_pram_ov	= PWR_COIL_OV;
	g_st_pwr_err_coil.b8_err		= BFALSE;
	g_st_pwr_err_coil.st_tim_fault.u16_cnt		= 0u;
	g_st_pwr_err_coil.st_tim_fault.u16_tim_old	= comm_tim_get_currt_cnt();
	g_st_pwr_err_coil.st_tim_reco.u16_cnt		= 0u;
	g_st_pwr_err_coil.st_tim_reco.u16_tim_old	= comm_tim_get_currt_cnt();
}

static void hmi_pwr_monitor(uint16_t u16_pwr_val, pwr_monitor_sta_t *stp_pwr_sta)
{
	uint32_t	u32_dat_tmp	= 0u;
	if((stp_pwr_sta->u16_pram_uv < u16_pwr_val) &&\
	(u16_pwr_val < stp_pwr_sta->u16_pram_ov))
	{
		if(stp_pwr_sta->st_tim_reco.u16_cnt	< PWR_FILT_TIM)
		{
			u32_dat_tmp	= comm_tim_calc_diff(&stp_pwr_sta->st_tim_reco.u16_tim_old);
			stp_pwr_sta->st_tim_reco.u16_cnt	+= (uint16_t)u32_dat_tmp;
		}
		else
		{
			stp_pwr_sta->b8_err	= BFALSE;
		}
		stp_pwr_sta->st_tim_fault.u16_cnt		= 0u;
		stp_pwr_sta->st_tim_fault.u16_tim_old	= comm_tim_get_currt_cnt();
	}
	else
	{
		if(stp_pwr_sta->st_tim_fault.u16_cnt	< PWR_FILT_TIM){
			u32_dat_tmp	= comm_tim_calc_diff(&stp_pwr_sta->st_tim_fault.u16_tim_old);
			stp_pwr_sta->st_tim_fault.u16_cnt	+= (uint16_t)u32_dat_tmp;
		}
		else{
			stp_pwr_sta->b8_err	= BTRUE;
		}
		stp_pwr_sta->st_tim_reco.u16_cnt		= 0u;
		stp_pwr_sta->st_tim_reco.u16_tim_old	= comm_tim_get_currt_cnt();
	}
}

static void hmi_fill_dev_diag(void)
{
	uint16_t	u16a_adc_raw_dat[10u]	= {0u};
	
	/* Power Monitor */
	adc_get_raw_dat(u16a_adc_raw_dat);//获取所有的ADC值
	/* POWER IN = ADC_VAL * (20 + 20 + 3.9) / 3.9 */
	/*
	u32_dat_tmp = adc_calc_voltage(u16a_adc_raw_dat[0], u16a_adc_raw_dat[3]);
	g_st_app_hmi_dat[0].st_dev_sta.u16_pwr_in	= (uint16_t)(u32_dat_tmp * 1.125641);
	*/
	/* g_st_app_hmi_dat[0].st_dev_sta.u16_pwr_in	= u16a_adc_raw_dat[0]; */
	/* POWER Coils = ADC_VAL * (16 + 16 + 6.8) / 6.8 */
	/*
	 u32_dat_tmp = adc_calc_voltage(u16a_adc_raw_dat[1], u16a_adc_raw_dat[3]);
	 g_st_app_hmi_dat[0].st_dev_sta.u16_pwr_coil	= (uint16_t)(u32_dat_tmp * 0.5705882);
	 */
	/* g_st_app_hmi_dat[0].st_dev_sta.u16_pwr_coil	= u16a_adc_raw_dat[1]; */
	
	g_st_ram1.run_display_data.instrument_hmi.u16_pwr_in= u16a_adc_raw_dat[1];//电源
	g_st_ram2.run_display_data.instrument_hmi.u16_pwr_in= u16a_adc_raw_dat[1];//电源
	g_st_ram1.run_display_data.instrument_hmi.u16_pwr_coil= u16a_adc_raw_dat[0];//线圈
	g_st_ram2.run_display_data.instrument_hmi.u16_pwr_coil= u16a_adc_raw_dat[0];//线圈
	g_st_ram1.run_display_data.instrument_hmi.u16_run_temper=u16a_adc_raw_dat[3];//温度
	g_st_ram2.run_display_data.instrument_hmi.u16_run_temper=u16a_adc_raw_dat[3];//温度
	g_st_ram1.run_display_data.instrument_hmi.u16_adc_vref=u16a_adc_raw_dat[4];//参考
	g_st_ram2.run_display_data.instrument_hmi.u16_adc_vref=u16a_adc_raw_dat[4];//参考

	
	hmi_pwr_monitor(u16a_adc_raw_dat[1], &g_st_pwr_err_vin);//输入电压上下限监控
	hmi_pwr_monitor(u16a_adc_raw_dat[0], &g_st_pwr_err_coil);//线圈电压上下限监控
	if (g_st_pwr_err_vin.b8_err==BTRUE)
	  {
			g_st_ram1.run_display_data.instrument_hmi.u8_dev_fault |= BF_DIAG1_PWR; //置电源电压故障
		  g_st_ram2.run_display_data.instrument_hmi.u8_dev_fault |= BF_DIAG1_PWR; //置电源电压故障
	  }
	else
	  {
			g_st_ram1.run_display_data.instrument_hmi.u8_dev_fault &= ~BF_DIAG1_PWR; //清电源电压故障
		  g_st_ram2.run_display_data.instrument_hmi.u8_dev_fault &= ~BF_DIAG1_PWR; //清电源电压故障
			//led_set_red(BFALSE);
		  //g_st_ram1.run_display_data.instrument_hmi.u16_led &= (uint16_t)~RED_LED_LIGHT; //红灯灭 指示
		  //g_st_ram2.run_display_data.instrument_hmi.u16_led &= (uint16_t)~RED_LED_LIGHT; //红灯灭 指示
		}
	if (g_st_pwr_err_coil.b8_err==BTRUE)
	  {
			g_st_ram1.run_display_data.instrument_hmi.u8_dev_fault |= BF_DIAG1_CWR; //置线圈电压故障
		  g_st_ram2.run_display_data.instrument_hmi.u8_dev_fault |= BF_DIAG1_CWR; //置线圈电压故障
	  }
	else
	  {
			g_st_ram1.run_display_data.instrument_hmi.u8_dev_fault &= ~BF_DIAG1_CWR; //清线圈电压故障
		  g_st_ram2.run_display_data.instrument_hmi.u8_dev_fault &= ~BF_DIAG1_CWR; //清线圈电压故障
			//led_set_red(BFALSE);
		  //g_st_ram1.run_display_data.instrument_hmi.u16_led &= (uint16_t)~RED_LED_LIGHT; //红灯灭 指示
		  //g_st_ram2.run_display_data.instrument_hmi.u16_led &= (uint16_t)~RED_LED_LIGHT; //红灯灭 指示
			
		}
	/* Safety BUS */
	
}
